using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(lwAstarNode))]
[CanEditMultipleObjects]
public class lwAstarNodeInspector : Editor {

	private bool m_bShowNeighbors = true;

	public static lwAstarNode SubselectedDest = null;
	public static lwAstarNode previousSelection = null;

	static public Vector3 m_vCreationOffsetUp = new Vector3(0, 100, 0);
	static public Vector3 m_vCreationOffsetRight = new Vector3(100, 0, 0);
	public enum NodeCreationLinkMode
	{
		no_link,
		forward_link,
		back_link,
		dual_link
	}

	static public NodeCreationLinkMode LinkMode = NodeCreationLinkMode.dual_link;
	public float m_UniformWeight = 1;

	[DrawGizmo(/*GizmoType.Pickable | */GizmoType.NotSelected | GizmoType.Selected | GizmoType.Active | GizmoType.SelectedOrChild)]
	static void RenderCustomGizmo(Transform objectTransform, GizmoType gizmoType)
	{
		lwAstarNode node = objectTransform.gameObject.GetComponent<lwAstarNode>();

		if((gizmoType&GizmoType.NotSelected) != 0)
		{
			if (previousSelection!=null && Selection.activeGameObject != previousSelection.gameObject && SubselectedDest != null)
			{
				SubselectedDest.m_bHighLight = false;
			}
		}

		if(node!=null)
		{
			if (((gizmoType&GizmoType.Active) != 0) || ((gizmoType&GizmoType.Selected) != 0))
			{
				Gizmos.color = Color.cyan;
				Gizmos.DrawCube(objectTransform.position, Vector3.one * lwAstarNode.GizmoSize);
				if (node.m_Links != null)
				{
					foreach (lwAstarNode.lwAstarLink link in node.m_Links)
					{
						Vector3 unitDir = (link.dest.transform.position - objectTransform.position).normalized;
						Gizmos.DrawLine(objectTransform.position + unitDir * lwAstarNode.GizmoSize, link.dest.transform.position - unitDir * lwAstarNode.GizmoSize);
						Gizmos.DrawCube(link.dest.transform.position - (lwAstarNode.GizmoSize * unitDir), Vector3.one * 4.0f);
					}
				}
			}
		}
	}


	void RemoveAllLinksBetweenSelection(List<lwAstarNode> nodes)
	{
		foreach (lwAstarNode node in nodes)
		{
			List<lwAstarNode.lwAstarLink> links = new List<lwAstarNode.lwAstarLink>();
			foreach (lwAstarNode.lwAstarLink link in node.m_Links)
			{
				bool bFoundDestInSelection = false;
				foreach (lwAstarNode destNode in nodes)
				{
					bFoundDestInSelection |= link.dest == destNode;
				}
				if (!bFoundDestInSelection)
					links.Add(link);
			}
			node.m_Links = links.ToArray();
			EditorUtility.SetDirty(node.gameObject);
		}
	}

	public override void OnInspectorGUI()
	{
		bool bNeedRepaint = false;
	
		EditorGUIUtility.LookLikeInspector();

		if(targets.Length>1)
		{
			List<lwAstarNode> nodes = new List<lwAstarNode>();
			foreach (Object obj in targets)
			{
				lwAstarNode node = obj as lwAstarNode;
				if (node != null)
				{
					nodes.Add(node);
				}
			}


			if (GUILayout.Button("\nAdd All possible links between selection\n"))
			{
				foreach (lwAstarNode node in nodes)
				{
					List<lwAstarNode.lwAstarLink> links = new List<lwAstarNode.lwAstarLink>();
					links.AddRange(node.m_Links);
					foreach (lwAstarNode dest in nodes)
					{
						if(dest != node)
						{
							bool bAlreadyExists = false;
							foreach (lwAstarNode.lwAstarLink existingLinks in links)
							{
								if(existingLinks.dest == dest)
									bAlreadyExists = true;
							}
						
							if( !bAlreadyExists )
							{
								lwAstarNode.lwAstarLink link = new lwAstarNode.lwAstarLink(dest);
								//link.dest = dest;
								link.cost = lwAstarNode.ComputeHeuristic(node, dest);
								links.Add(link);
							}
						}
					}
					node.m_Links = links.ToArray();
					EditorUtility.SetDirty(node.gameObject);
				}
			}

			if (GUILayout.Button("\nRemove All links between selection\n"))
			{
				RemoveAllLinksBetweenSelection(nodes);
			}

			m_UniformWeight = EditorGUILayout.FloatField("Uniform Weight ", m_UniformWeight, "TextField");
			if (GUILayout.Button("\nSet Uniform Weight to All links between selection\n"))
			{
				foreach (lwAstarNode node in nodes)
				{
					foreach (lwAstarNode dest in nodes)
					{
						foreach (lwAstarNode.lwAstarLink existingLinks in node.m_Links)
						{
							if (existingLinks.dest == dest)
								existingLinks.weight = m_UniformWeight;
						}
					}
					EditorUtility.SetDirty(node.gameObject);
				}
			}

			if (nodes.Count == 2)
			{
				if (GUILayout.Button("\nBuild Up Vector\n"))
				{
					int UpIdx = (nodes[0].transform.position.y > nodes[1].transform.position.y)?0:1;
					m_vCreationOffsetUp = nodes[UpIdx].transform.position - nodes[1-UpIdx].transform.position;
				}

				if (GUILayout.Button("\nBuild Right Vector\n"))
				{
					int RightIdx = (nodes[0].transform.position.x > nodes[1].transform.position.x)?0:1;
					m_vCreationOffsetRight = nodes[RightIdx].transform.position - nodes[1 - RightIdx].transform.position;
				}
			}			
		}
		else
		{
			lwAstarNode CurrentTarget = target as lwAstarNode;

			if (previousSelection != CurrentTarget)
			{
				if (SubselectedDest!=null)
					SubselectedDest.m_bHighLight = false;
				previousSelection = CurrentTarget;
			}


			m_vCreationOffsetUp = EditorGUILayout.Vector3Field("Creation Offset Up", m_vCreationOffsetUp);
			m_vCreationOffsetRight = EditorGUILayout.Vector3Field("Creation Offset Right", m_vCreationOffsetRight);

			EditorGUILayout.BeginVertical();
			EditorGUILayout.BeginHorizontal();

			float buttonWidth = Screen.width/3.0f - 5;

			if (GUILayout.Button("Create UpLeft", new GUILayoutOption[] { GUILayout.Width(buttonWidth)}))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition + m_vCreationOffsetUp - m_vCreationOffsetRight;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;

				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch( LinkMode )
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}
			if (GUILayout.Button("Create Up", new GUILayoutOption[] { GUILayout.Width(buttonWidth) }))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition + m_vCreationOffsetUp;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;
					
				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch (LinkMode)
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}
			if (GUILayout.Button("Create UpRight", new GUILayoutOption[] { GUILayout.Width(buttonWidth) }))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition + m_vCreationOffsetUp + m_vCreationOffsetRight;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;
				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch (LinkMode)
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}
			EditorGUILayout.EndHorizontal();
			EditorGUILayout.BeginHorizontal();
			if (GUILayout.Button("Create Left", new GUILayoutOption[] { GUILayout.Width(buttonWidth) }))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition - m_vCreationOffsetRight;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;
				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch (LinkMode)
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}

			LinkMode = (NodeCreationLinkMode)EditorGUILayout.Popup((int)LinkMode, System.Enum.GetNames(typeof(NodeCreationLinkMode)), new GUILayoutOption[] { GUILayout.Width(buttonWidth), GUILayout.Height(25) });


			if (GUILayout.Button("Create Right", new GUILayoutOption[] { GUILayout.Width(buttonWidth) }))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition + m_vCreationOffsetRight;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;
				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch (LinkMode)
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}
			EditorGUILayout.EndHorizontal();
			EditorGUILayout.BeginHorizontal();

			if (GUILayout.Button("Create DownLeft", new GUILayoutOption[] { GUILayout.Width(buttonWidth) }))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition - m_vCreationOffsetUp - m_vCreationOffsetRight;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;
				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch (LinkMode)
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}
			if (GUILayout.Button("Create Down", new GUILayoutOption[] { GUILayout.Width(buttonWidth) }))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition - m_vCreationOffsetUp;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;
				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch (LinkMode)
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}
			if (GUILayout.Button("Create DownRight", new GUILayoutOption[] { GUILayout.Width(buttonWidth) }))
			{
				GameObject newNodeObj = new GameObject("PathNode");
				newNodeObj.transform.parent = CurrentTarget.transform.parent;
				newNodeObj.transform.localPosition = CurrentTarget.transform.localPosition - m_vCreationOffsetUp + m_vCreationOffsetRight;

				lwAstarNode newNode = newNodeObj.AddComponent(typeof(lwAstarNode)) as lwAstarNode;
				lwAstarNode.lwAstarLink newLink = new lwAstarNode.lwAstarLink(newNode);
				lwAstarNode.lwAstarLink newBackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
				lwAstarNode.lwAstarLink[] newBackLinkArray = new lwAstarNode.lwAstarLink[1];
				newBackLinkArray[0] = newBackLink;
				List<lwAstarNode.lwAstarLink> linklist = new List<lwAstarNode.lwAstarLink>();
				linklist.AddRange(CurrentTarget.m_Links);
				linklist.Add(newLink);
				switch (LinkMode)
				{
					case NodeCreationLinkMode.no_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						break;
					case NodeCreationLinkMode.forward_link:
						newNode.m_Links = new lwAstarNode.lwAstarLink[0];
						CurrentTarget.m_Links = linklist.ToArray();
						break;
					case NodeCreationLinkMode.back_link:
						newNode.m_Links = newBackLinkArray;
						break;
					case NodeCreationLinkMode.dual_link:
						newNode.m_Links = newBackLinkArray;
						CurrentTarget.m_Links = linklist.ToArray();
						break;
				}

				CurrentTarget.transform.parent.gameObject.GetComponent<lwAstarGraph>().AddNode(newNode);
				Selection.objects = new Object[] { newNodeObj };
			}
			EditorGUILayout.EndHorizontal();

			EditorGUILayout.EndVertical();
			EditorGUILayout.BeginVertical();
			EditorGUILayout.BeginHorizontal();
			EditorGUIUtility.LookLikeInspector();
			CurrentTarget.blocked = GUILayout.Toggle(CurrentTarget.blocked, "Blocked");
			EditorGUILayout.EndHorizontal();
			EditorGUILayout.BeginHorizontal();
			m_bShowNeighbors = EditorGUILayout.Foldout(m_bShowNeighbors, "Neighbors");
			EditorGUILayout.LabelField((CurrentTarget.m_Links != null ? "Size " + CurrentTarget.m_Links.Length.ToString() : "null"));
			EditorGUILayout.EndHorizontal();

			if (m_bShowNeighbors && CurrentTarget.m_Links != null && CurrentTarget.m_Links.Length > 0)
			{
				List<lwAstarNode.lwAstarLink> linkToKeep = new List<lwAstarNode.lwAstarLink>();
				foreach (lwAstarNode.lwAstarLink link in CurrentTarget.m_Links)
				{
					EditorGUILayout.BeginHorizontal();

					EditorGUIUtility.LookLikeControls(1, 1);
					if (link.dest == null)
					{
						if (GUILayout.Button("?"))
						{
							link.UpdateLinkRef();
						}
					}
					else
					{
						if (GUILayout.Button(link.dest.name))
						{
							if (SubselectedDest != link.dest && SubselectedDest != null)
								SubselectedDest.m_bHighLight = false;
							link.dest.m_bHighLight = true;
							SubselectedDest = link.dest;
							EditorUtility.SetDirty(SubselectedDest);
						}
					}
					EditorGUIUtility.LookLikeControls(50, 20);
					link.weight = EditorGUILayout.FloatField("weight ", link.weight, "TextField");
					EditorGUIUtility.LookLikeControls(75, 20);
					link.weightMultiplier = EditorGUILayout.FloatField("weight Xier ", link.weightMultiplier, "TextField");
					EditorGUIUtility.LookLikeControls(65, 20);
					link.costMultiplier = EditorGUILayout.FloatField("cost Xier ", link.costMultiplier, "TextField");
					EditorGUILayout.LabelField("cost " + ( link.cost * link.costMultiplier + link.weight * link.weightMultiplier ));
					if (!GUILayout.Button("del"))
					{
						linkToKeep.Add(link);
					}
					else if (SubselectedDest == link.dest)
					{
						SubselectedDest.m_bHighLight = false;
						SubselectedDest = null;
					}
					EditorGUILayout.EndHorizontal();
				}
				if (linkToKeep.Count < CurrentTarget.m_Links.Length)
				{
					CurrentTarget.m_Links = linkToKeep.ToArray();
					EditorUtility.SetDirty(CurrentTarget);
				}
			}
			EditorGUILayout.EndVertical();
			Rect previous = GUILayoutUtility.GetLastRect();
			Rect DropZoneRect = new Rect(previous.xMin, previous.yMax + 10, previous.width, 50);
			GUI.Box(DropZoneRect,"\nDrop Nodes to Create link");

			Rect DualDropZoneRect = new Rect(DropZoneRect.xMin, DropZoneRect.yMax + 10, DropZoneRect.width, 50);
			GUI.Box(DualDropZoneRect, "\nDrop Nodes to Create Dual link");


			EventType eventType = Event.current.type;
			if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform)
			{
				bool bDualLink = DualDropZoneRect.Contains(Event.current.mousePosition);
				if (DropZoneRect.Contains(Event.current.mousePosition) || bDualLink)
				{
					DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

					if (eventType == EventType.DragPerform)
					{
						DragAndDrop.AcceptDrag();

						List<lwAstarNode> newlist = new List<lwAstarNode>();

						if (CurrentTarget.m_Links != null && CurrentTarget.m_Links.Length>0)
						{
							foreach (lwAstarNode.lwAstarLink link in CurrentTarget.m_Links)
							{
								if(!newlist.Contains(link.dest))
									newlist.Add(link.dest);
							}
						}
						
						foreach(Object obj in DragAndDrop.objectReferences)
						{
							GameObject Gobj = obj as GameObject;
							if( Gobj!= null )
							{
								lwAstarNode node = Gobj.GetComponent<lwAstarNode>();
								if ( node != null && node != CurrentTarget )
								{
									if ( !newlist.Contains( node ) )
										newlist.Add( node );

									if(bDualLink)
									{
										bool bBackLinkAreadyExist = false;
										List<lwAstarNode.lwAstarLink> newBackLinklist = new List<lwAstarNode.lwAstarLink>();


										foreach (lwAstarNode.lwAstarLink destlink in node.m_Links)
										{
											newBackLinklist.Add(destlink);
											bBackLinkAreadyExist |= destlink.dest == CurrentTarget;
										}
										
										if( !bBackLinkAreadyExist )
										{
											lwAstarNode.lwAstarLink BackLink = new lwAstarNode.lwAstarLink(CurrentTarget);
											//BackLink.dest = CurrentTarget;
											BackLink.cost = lwAstarNode.ComputeHeuristic(node, CurrentTarget);
											newBackLinklist.Add(BackLink);
											node.m_Links = newBackLinklist.ToArray();
											EditorUtility.SetDirty(node.gameObject);
										}
									}
								}
							}
						}
						
						lwAstarNode.lwAstarLink[] newArray = new lwAstarNode.lwAstarLink[newlist.Count];
						for(int i = 0; i<newlist.Count; ++i)
						{
							lwAstarNode dest = newlist[i] as lwAstarNode;
							newArray[i] = new lwAstarNode.lwAstarLink(dest);
							//newArray[i].dest = dest;
							newArray[i].cost = lwAstarNode.ComputeHeuristic(CurrentTarget, dest);
						}
						
						CurrentTarget.m_Links = newArray;

						EditorUtility.SetDirty(target);
						
						bNeedRepaint = true;
					}

					Event.current.Use();
				}
			}
			
			if(bNeedRepaint)
				Repaint();
		}
	}
}
